<?php

namespace app\common\audit\logic;

use app\common\BaseLogic;
use app\common\system\logic\UserDepartmentLogic;
use app\common\system\logic\UserLogic;
use app\common\system\logic\UserRoleLogic;
use think\Exception;

class AuditProcessLogic extends BaseLogic
{
    // 当前订单
    protected $masterData = [];
    protected $user = [];

    // 当前审核流的配置
    protected $cfg = [];
    protected $grouped = [];
    protected $groupParent = [];

    /**
     * @param $masterData 主流程信息
     * @param $user     当前用户的信息
     * @param $options ['type'=> audit_config.timing,'company_id'=>targetCompany.id]
     * @return array 返回审核流程
     */
    public function getAuditProcess(&$masterData, &$user, $options)
    {
        $this->masterData = $masterData;
        $this->user = $user;

        $targetCompanyId = $options['company_id'];
        // 从数据库中，获取审核流程的配置
        $auditCfgLogic = new AuditConfigLogic();
        $audit = $auditCfgLogic->getAudit($targetCompanyId, $options['timing']);
        if (empty($audit['condition'])) return [];

        // 获取审核流程
        $this->cfg = $audit['condition'];
        $parent = array_shift($this->cfg);
        $this->grouped = $this->getGroupedCondition();

        return $this->getMatchedProcess($parent, []);
    }

    // 条件分组
    public function getGroupedCondition()
    {
        $groups = [];
        foreach ($this->cfg as $row) {
            if ($row['type'] == 3) {
                if (!isset($groups[$row['groupId']])) {
                    $groups[$row['groupId']]['list'] = [];
                }

                if (!isset($row['data']['condition']) || count($row['data']['condition']) == 0) {
                    // 出现多个默认空条件，按第一个条件审核
                    if (!isset($groups[$row['groupId']]['default'])) $groups[$row['groupId']]['default'] = $row;
                }

                array_push($groups[$row['groupId']]['list'], $row);
            }
        }

        return $groups;
    }

    // 获取匹配的审核流程
    public function getMatchedProcess($parent, $data)
    {
        $children = $this->getDirectChildren($parent);
        if (empty($children)) {
            $children = $this->getGroupChildren();
        }

        $childrenAmount = count($children);
        if ($childrenAmount > 1) {
            $matched = [];
            // 遍历条件组，未匹配到条件走默认流程
            $currentGroup = $children[0];
            foreach ($this->grouped[$currentGroup['groupId']]['list'] as $conditionGroups) {
                $checkRs = $this->checkMatched($conditionGroups);
                if ($checkRs) {
                    $matched = $conditionGroups;
                    break;
                }
            }

            // 未匹配到就走默认流程
            if (empty($matched)) {
                if (isset($this->grouped[$currentGroup['groupId']]['default'])) {
                    $matched = $this->grouped[$currentGroup['groupId']]['default'];
                } else {
                    return [];
                }
            }

            // 检测parentGroup是否有master
            array_push($this->groupParent, $matched);
            $data = $this->getMatchedProcess($matched, $data);
        }

        if ($childrenAmount == 1) {
            array_push($data, $children[0]);
            $data = $this->getMatchedProcess($children[0], $data);
        }

        return $data;
    }

    // 获取节点的子节点
    public function getDirectChildren($parent)
    {
        $arr = [];
        foreach ($this->cfg as $key => $row) {
            // 非直接子节点
            if (count($row['pids']) > 1) continue;

            if (in_array($parent['id'], $row['pids'])) {
                array_push($arr, $row);
            }
        }

        return $arr;
    }

    // 检测条件是否符合
    public function checkMatched($conditionGroups)
    {
        $matched = false;
        if (!isset($conditionGroups['data']['condition'])) return false;
        $groups = $conditionGroups['data']['condition'];

        // 获取用户所有角色
        $userRoleLogic = new UserRoleLogic();
        $roleIds = $userRoleLogic->getUserRole($this->user['id']);
        // 获取用户所有的部门
        $userDptLogic = new UserDepartmentLogic();
        $dptIds = $userDptLogic->getUserDepartment($this->user['id']);

        foreach ($groups as $group) {
            foreach ($group as $condition) {
                // 判断是否存在于审核
                if ($condition['id'] == 'user' && isset($condition['value']) && in_array($this->user['id'], $condition['value'])) {
                    $matched = true;
                    break 2;
                }

                if ($condition['id'] == 'role' && isset($condition['value'])) {
                    $intersect = array_intersect($roleIds, $condition['value']);
                    if (!empty($intersect)) {
                        // 判断角色
                        $matched = true;
                        break 2;
                    } else {
                        continue;
                    }
                }

                // 部门条件
                if ($condition['id'] == 'department' && isset($condition['value'])) {
                    $intersect = array_intersect($dptIds, $condition['value']);
                    if (!empty($intersect)) {
                        $matched = true;
                        break 2;
                    } else {
                        continue;
                    }
                }

                // 没有主流程信息，检测过滤
                if (empty($this->masterData)) continue;

                // 酒店条件
                if ($condition['id'] == 'hotel' && isset($condition['value']) && in_array($this->masterData['store_id'], $condition['value'])) {
                    $matched = true;
                    break 2;
                }

                // 信息类型条件
                if ($condition['id'] == 'category_id' && isset($condition['value']) && in_array($this->masterData['category_id'], $condition['value'])) {
                    $matched = true;
                    break 2;
                }

                // 合作模式条件
                if ($condition['id'] == 'cooperation_mode' && isset($condition['value']) && in_array($this->masterData['cooperation_id'], $condition['value'])) {
                    $matched = true;
                    break 2;
                }
            }
        }

        return $matched;
    }

    // 获取条件组的子节点
    public function getGroupChildren()
    {
        $parent = array_pop($this->groupParent);
        if (empty($parent)) return [];

        $arr = [];
        foreach ($this->cfg as $key => $row) {
            // 直接子节点
            if (count($row['pids']) < 2) continue;
            if (in_array($parent['id'], $row['pids'])) {
                array_push($arr, $row);
            }
        }

        if (empty($arr)) {
            $arr = $this->getGroupChildren();
        }

        return $arr;
    }

    // 获取所有审核条件
    public function getAuditsFromProcess($process)
    {
        $audits = [];
        foreach ($process as $row) {
            if ($row['type'] == 2) {
                array_push($audits, $row);
            }
        }

        return empty($audits) ? [] : array_column($audits, null, 'id');
    }


    /**
     * 获取下一个审批
     * @param $process
     * @param $user
     * @param string $currentAuditId
     * @return array
     * @throws Exception
     */
    public function getNextAudit(&$process, &$user, $currentAuditId = '')
    {
        $next = [];
        $isLast = false;
        $audits = $this->getAuditsFromProcess($process);

        if (empty($currentAuditId)) {
            $next = array_shift($audits);
            if (empty($next)) throw new Exception("尚未设置审核流程");
        } else {
            $keys = array_keys($audits);
            $index = array_search($currentAuditId, $keys);
            if ($index !== false && isset($keys[$index + 1])) {
                $index = $keys[$index + 1];
                $next = $audits[$index];
            } else {
                $isLast = true;
            }
        }

        if (empty($next)) return [[], [], $isLast];

        $userLogic = new UserLogic();
        // 不再支持同时多人审核的方式
        if (!empty($next['data']['checkedUserList'])) {
            $userId = $next['data']['checkedUserList'][0];
            $cuser = $userLogic->getUser($userId, ['id', 'realname', 'status']);
        }

        // 按照角色查找审核者
        if (!empty($next['data']['role'])) {
            $cuser = $userLogic->getDptRoleUser($user['id'], $next['data']['role']);
        }

        if (empty($cuser)) throw new Exception("未找到匹配的审核人员");

        return [$next, $cuser, $isLast];
    }

    // 获取当前审核的所有抄送，可能存在多组抄送，用于创建
    public function getAuditCopy(&$process, &$audit, $user)
    {
        $users = [];
        $matchedCopy = [];
        $isCurrentAudit = false;
        foreach ($process as $row) {
            // 匹配审核人
            if ($row['id'] == $audit['id'] && !$isCurrentAudit) {
                $isCurrentAudit = true;
                continue;
            }

            // 已经匹配到审核人,
            if ($isCurrentAudit && $row['type'] == 4) {
                array_push($matchedCopy, $row);
            }

            // 已经匹配到审核人，再次循环到审核人，匹配抄送结束
            if ($isCurrentAudit && $row['type'] == 2) {
                break;
            }
        }

        $userLogic = new UserLogic();
        foreach ($matchedCopy as $copy) {
            if (!empty($copy['data']['checkedUserList'])) {
                foreach ($copy['data']['checkedUserList'] as $userId) {
                    // 获取要抄送的人
                    $targetUser = $userLogic->getUser($userId);
                    if ($targetUser['id'] > 0) array_push($users, $targetUser);
                }
            }

            // 按照角色查找审核者
            if (!empty($copy['data']['role'])) {
                $users = $userLogic->getDptRoleUser($user['id'], $copy['data']['role']);
            }
        }

        return $users;
    }

    // 获取审核项的所有用户信息
    public function getAuditItemUsers($audit, $user)
    {
        $users = [];
        $userLogic = new UserLogic();
        // 审核者
        if (!empty($audit['data']['checkedUserList'])) {
            foreach ($audit['data']['checkedUserList'] as $userId) {
                // 获取提交者
                $targetUser = $userLogic->getUser($userId);
                if ($targetUser['id'] > 0) array_push($users, $targetUser);
            }
        }

        // 按照角色查找审核者
        if (!empty($audit['data']['role'])) {
            $users = $userLogic->getDptRoleUser($user['id'], $audit['data']['role']);
        }

        return $users;
    }

    public function getCopyItemUser($copy, $user)
    {
        $users = [];
        $userLogic = new UserLogic();
        if (!empty($copy['data']['checkedUserList'])) {
            foreach ($copy['data']['checkedUserList'] as $userId) {
                // 获取要抄送的人
                $targetUser = $userLogic->getUser($userId);
                if ($targetUser['id'] > 0) array_push($users, $targetUser);
            }
        }

        // 按照角色查找审核者
        if (!empty($copy['data']['role'])) {
            $users = $userLogic->getDptRoleUser($user['id'], $copy['data']['role']);
        }

        return $users;
    }
}